<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        div {
            width: 100px;
            height: 100px;
            background-color: red;
            transition: all 0.5s;
        }
    </style>
</head>

<body>
    <div id="box"></div>
    <script>
        const move = (el, {
            x = 0,
            y = 0
        } = {}, end = () => {}) => {
            el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
            el.addEventListener(
                "transitionend",
                () => {
                    console.log("end");
                    end();
                },
                false
            );
        };
        const boxEl = document.getElementById("box");
        // 回调函数嵌套回调函数，修改不方便
        // document.addEventListener('click', () => {
        //     move(boxEl, {
        //         x: 150
        //     }, () => {
        //         move(boxEl, {
        //             x: 150,
        //             y: 150
        //         }, () => {
        //             move(boxEl, {
        //                 y: 150
        //             }, () => {
        //                 move(boxEl)
        //             })
        //         })
        //     })
        // }, false);
        // 使用Promise进行回调
        const movePromise = (el, point) => {
            return new Promise((resolve) => {
                move(el, point, () => {
                    resolve();
                });
            });
        };
        document.addEventListener(
            "click",
            () => {
                movePromise(boxEl, {
                        x: 150,
                    })
                    .then(() => {
                        return movePromise(boxEl, {
                            x: 150,
                            y: 150,
                        });
                    })
                    .then(() => {
                        return movePromise(boxEl, {
                            y: 150,
                        });
                    })
                    .then(() => {
                        return movePromise(boxEl, {
                            x: 0,
                            y: 0,
                        });
                    });
            },
            false
        );
        // 1、catch方法的作用
        // 专门处理rejected状态
        // catch本质上是then的特例
        // then(null, err => {})
        // 2、基本用法
        new Promise((resolve, reject) => {
                reject("reason");
            })
            .then((data) => {
                console.log(data);
            })
            .catch((err) => {
                // 相当于.then
                console.log(err);
                // return undefined
                throw new Error("resaon");
            })
            .then((data) => {
                console.log(data);
            })
            .catch((err) => {
                console.log(err);
            });
        // catch()可以捕获它前面的错误
        // 一般总是建议Promise对象后面要跟catch方法，这样可以处理Promise内部发生的错误

        // **************************************
        // Promise.resolve()
        // 是成功状态的Promise的一种简写
        new Promise((resolve) => resolve("foo"));
        // 简写
        Promise.resolve("foo");

        // 参数
        // 一般参数
        Promise.resolve("foo").then((data) => {
            console.log(data);
        });
        // Promise
        const p1 = new Promise((resolve) => {
            setTimeout(resolve, 1000, "我执行了");
        });
        Promise.resolve(p1).then((data) => {
            console.log(data);
        });
        // 等价于
        p1.then((data) => {
            console.log(data);
        });
        console.log(Promise.resolve(p1) === p1);
        // 具有then方法的对象
        const thenable = {
            then(resolve, reject) {
                console.log("then");
            },
        };
        Promise.resolve(thenable).then(
            (data) => console.log(data),
            (err) => console.log(err)
        );
        // Promise.reject()
        // 失败状态Promise的一种简写形式
        new Promise((reject) => reject("foo"));
        // 简写
        // Promise.reject('foo');
        // 不管什么参数都会原封不动的向后传递，作为后续的方法的参数
        const p3 = new Promise((resolve) => {
            setTimeout(resolve, 1000, "我酷酷酷");
        });
        Promise.reject(p3).catch((err) => console.log(err));

        // **************************************
        // Promise.all()关注多个Promise对象的状态变化
        // 传入多个Promise实例，包装成一个新的Promise实例返回
        const delay = (ms) => {
            return new Promise((resolve) => {
                // ms秒后由等待状态变为成功状态
                setTimeout(resolve, ms);
            });
        };
        const p4 = delay(1000).then(() => {
            console.log("p4完成了");
            return Promise.reject("reason");
            // return 'p4'
        });
        const p5 = delay(2000).then(() => {
            console.log("p5完成了");
            // return Promise.reject('reason')
            return "p5";
        });
        // &&运算所有都resolve最终状态resolve,有一个reject最终状态reject
        // 第一个reject后与运算直接抛出reject
        const p = Promise.all([p4, p5]).then(
            (data) => {
                console.log(data);
            },
            (err) => {
                console.log(err);
            }
        );
        // Promise.race()  取决于第一个第一个成功就成功，第一个失败就失败
        // Promise.allSettled()  与传入状态无关，不管怎么样都成功
    </script>
</body>

</html>